package com.zxcz.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import com.zxcz.domain.PageResult;
import com.zxcz.domain.Resource;
import com.zxcz.domain.Result;
import com.zxcz.domain.User;
import com.zxcz.mapper.ResourceMapper;
import com.zxcz.mapper.UserMapper;
import com.zxcz.redis.RedisManager;
import com.zxcz.service.ResourceService;
import com.zxcz.tools.Constants;
import com.zxcz.tools.CustomHttpStatus;
import com.zxcz.tools.RedisKeyBuilder;
import com.zxcz.tools.ResultUtil;

@Service
public class ResourceServiceImpl implements ResourceService{
	@Autowired
	private ResourceMapper resourceMapper;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private RedissonClient redisson;
	private static final Log logger = LogFactory.getLog(ResourceServiceImpl.class);

	/**
	 * 分页方法
	 * @param pageNum 当前页数
	 * @param pageSize 每页显示的记录数
	 * @return PageResult 分页对象
	 */
	@Override
	public PageResult<Resource> queryPage(int pageNum, int pageSize, String name, String startTime, String endTime, String account) {
		// 起始位置
		int pageNumber = (pageNum-1) * pageSize;
		List<Resource> resourceList = resourceMapper.queryResourceCondition(pageNumber, pageSize, name, startTime, endTime, account);
		Long total = resourceMapper.getTotal(name, startTime, endTime, account);
		// 分页对象
		PageResult<Resource> pageResult = new PageResult<Resource>();
		pageResult.setRows(resourceList);
		pageResult.setTotal(total);
		
		return pageResult;
	}

	/**
	 * 根据id查找资源
	 * @param id
	 * @return Resource
	 */
	@Override
	public Resource findResourceById(int id) {
		return resourceMapper.findResourceById(id);
	}

	/**
	 * 添加资源
	 */
	@Override
	public Result<Object> insertResource(Resource resource) {
		RLock rLock = redisson.getLock("resourceLock");
		
		try {
			boolean res = rLock.tryLock(10, 5, TimeUnit.SECONDS);
			if(res) {
				// 获取登录账号
				String account = SecurityContextHolder.getContext().getAuthentication().getName();
				User user = userMapper.findUserByAccount(account);
				//获取版本号
				String version = getVersion(resource);
				resource.setVersion(version);
				//添加时间
				resource.setCreatedAt(new Date());
				resource.setUpdatedAt(new Date());
				resource.setUserId(user.getId());
				resourceMapper.insertResource(resource);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			return ResultUtil.generate(CustomHttpStatus.SERVER_ERROR);
		} finally {
			rLock.unlock();
		}
		
		return ResultUtil.generate(CustomHttpStatus.SUCCESS);
	}
	
	//删除资源
	@Override
	public Result<Object> deleteResource(int id) {
		RLock rLock = redisson.getLock("resourceLock");
		
		try {
			boolean res = rLock.tryLock(10, 5, TimeUnit.SECONDS);
			if(res) {
				//删除数据库数据
				resourceMapper.deleteResourceById(id);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return ResultUtil.generate(CustomHttpStatus.SERVER_ERROR);
		} finally {
			rLock.unlock();
		}
				
		return ResultUtil.generate(CustomHttpStatus.SUCCESS);
	}

	//更新资源
	@Override
	public Result<Object> updateResource(Resource resource) {
		RLock rLock = redisson.getLock("resourceLock");
		
		try {
			boolean res = rLock.tryLock(10, 5, TimeUnit.SECONDS);
			if(res) {
				//获取版本号
				String version = getVersion(resource);
				resource.setVersion(version);
				//更新时间
				resource.setUpdatedAt(new Date());
				//修改数据库
				resourceMapper.updateResource(resource);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return ResultUtil.generate(CustomHttpStatus.SERVER_ERROR);
		} finally {
			rLock.unlock();
		}
		
		return ResultUtil.generate(CustomHttpStatus.SUCCESS);
	}
	
	/**
	 * 获取版本号
	 * @param resource 需要生成版本号的资源
	 * @return String 版本号
	 */
	public String getVersion(Resource resource) {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		String dateNow = format.format(new Date());
		int code = 1;
		String version = dateNow + "-" + code;
		
		List<Resource> resourceList = resourceMapper.findResourceByName(resource.getName());
		//判断是否已经存在同名资源
		if(resourceList == null || resourceList.isEmpty()) {
			return version;
		} else {
			String versionDate = null;  //版本号-前的字符串
			List<String> versionList = new ArrayList<>();
			for(Resource re : resourceList) {
				versionDate = re.getVersion().substring(0,re.getVersion().indexOf('-'));
				//判断date是否一致
				if(dateNow.equals(versionDate)) {
					//取出date一致的版本号
					versionList.add(re.getVersion());
				}
			}
			
			//存在相同日期
			if(versionList != null && !versionList.isEmpty()) {
				//截取该日期-前的字符串
				versionDate = versionList.get(0).substring(0, versionList.get(0).indexOf('-'));
				String max = Collections.max(versionList);
				code = Integer.parseInt(max.substring(max.indexOf('-')+1)) + 1;
				version = versionDate + "-" + code;
			}
		}
		return version;
	}
	
	/**
	 * 根据ossObject获取资源对象
	 * @param ossObject
	 */
	@Override
	public Resource findResourceByOssObject(String ossObject) {
		return resourceMapper.findResourceByOssObject(ossObject);
	}
	
	@Override
	public PageResult userResourcePage(int pageNum, int pageSize, String name, String startTime, String endTime) {
		// 获取登录账号
		String account = SecurityContextHolder.getContext().getAuthentication().getName();
		
		// 起始位置
		int pageNumber = (pageNum-1) * pageSize;
		List<Resource> resourceList = resourceMapper.queryResourceCondition(pageNumber, pageSize, name, startTime, endTime, account);
		Long total = resourceMapper.getTotal(name, startTime, endTime, account);
		
		// 分页对象
		PageResult<Resource> pageResult = new PageResult<Resource>();
		pageResult.setRows(resourceList);
		pageResult.setTotal(total);
		return pageResult;
	}

	@Override
	public Result<Object> deleteResourceByUserId(Integer id) {
		resourceMapper.deleteResourceByUserId(id);
		return ResultUtil.generate(CustomHttpStatus.SUCCESS);
	}
	
}
